﻿<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="../helpproject.xsl" ?>
<topic template="Default" lasteditedby="Geert" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../helpproject.xsd">
  <title translate="true">Interaction with models</title>
  <body>
    <header>
      <para styleclass="Heading1"><text styleclass="Heading1" translate="true">Interaction with models</text></para>
    </header>
    <para styleclass="Normal"><text styleclass="Normal" translate="true">One of the most important reasons why a View Model is created is because it serves as the glue between a View and the Model. The communication between the View and the View Model is fully taken care of by WPF in the form of Bindings. The problem is that most of the time, a View Model is used to show a subset of a Model (which is, for example, a database entity).</text></para>
    <para styleclass="Normal"><text styleclass="Normal" translate="true">Most MVVM frameworks (actually, I haven&apos;t seen anyone not requiring manual updating) require manual updating, which brings us back to the stone age (remember the WinForms time setting the controls at startup, and reading the values at the end?). Catel solves this issue by providing convenience attributes that take care of this dumb getting/setting story between the View Model and the Model. Catel fully supports getting/setting the values from/to the Model, but believe me: you will love the attributes that are described next.</text></para>
    <para styleclass="Heading1"><text styleclass="Heading1" translate="true">ModelAttribute</text></para>
    <para styleclass="Normal"><text styleclass="Normal" translate="true">To be able to map values from/to a Model, it is important to know the actual Model. So, to let the View Model know what property represents the Model, </text><link displaytype="text" defaultstyle="true" type="topiclink" href="T_Catel_MVVM_ModelAttribute" styleclass="Normal" translate="true">ModelAttribute</link><text styleclass="Normal" translate="true"> can be used like shown below:</text></para>
    <para styleclass="Code Example"><text styleclass="Code Example" style="font-weight:normal; font-style:italic; color:#000000;" translate="true">/// &lt;summary&gt;</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:italic; color:#000000;" translate="true">/// Gets or sets the person.</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:italic; color:#000000;" translate="true">/// &lt;/summary&gt;</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">[Model]</text><br/><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000000;" translate="true">public</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">Person</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">Person</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">{</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true"> &#160; &#160;</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">get</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">{</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000000;" translate="true">return</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">GetValue&lt;Person&gt;(PersonProperty);</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">}</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true"> &#160; &#160;</text><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000000;" translate="true">private</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">set</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">{</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">SetValue(PersonProperty,</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">value);</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">}</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">}</text><br/><br/><text styleclass="Code Example" style="font-weight:normal; font-style:italic; color:#000000;" translate="true">/// &lt;summary&gt;</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:italic; color:#000000;" translate="true">/// Register the Person property so it is known in the class.</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:italic; color:#000000;" translate="true">/// &lt;/summary&gt;</text><br/><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000000;" translate="true">public</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000000;" translate="true">static</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000000;" translate="true">readonly</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">PropertyData</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">PersonProperty</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">=</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">RegisterProperty(&quot;Person&quot;,</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000000;" translate="true">typeof</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">(Person));</text></para>
    <para styleclass="Normal"><text styleclass="Normal" translate="true">A Model setter is normally written as private (you normally don&apos;t want a UI to be able to change a Model), but the getter is public because you might want to read info from it.</text></para>
    <para styleclass="Notes"><text styleclass="Notes" translate="true">Note that you should use the vmpropmodel code snippet to create Model properties</text></para>
    <para styleclass="Normal"><text styleclass="Normal" translate="true">Models in Catel are handled as very, very special objects. This means that as soon as a Model is set, Catel tries to call the </text><text styleclass="Normal" style="font-style:italic;" translate="true">IEditableObject.BeginEdit</text><text styleclass="Normal" translate="true"> method. Then, as soon as the Model is changed without being saved, or if the View Model is canceled, the Model is correctly canceled via </text><text styleclass="Normal" style="font-style:italic;" translate="true">IEditableObject.CancelEdit</text><text styleclass="Normal" translate="true">. If the Model is saved, the active Models will be committed via </text><text styleclass="Normal" style="font-style:italic;" translate="true">IEditableObject.EndEdit</text><text styleclass="Normal" translate="true">. I will leave the rest of the magic out of this article, but if you have any questions about it, don&apos;t hesitate to contact us!</text></para>
    <para styleclass="Heading1"><text styleclass="Heading1" translate="true">ViewModelToModelAttribute</text></para>
    <para styleclass="Normal"><text styleclass="Normal" translate="true">Now that we know how to declare a property has a Model, it is time to learn how we can communicate with it. Normally, you would have to watch the Model to make sure it is synchronized correctly when the Model is updated. With Catel, this is not necessary any longer. Simply use </text><link displaytype="text" defaultstyle="true" type="topiclink" href="T_Catel_MVVM_ViewModelToModelAttribute" styleclass="Normal" translate="true">ViewModelToModelAttribute</link><text styleclass="Normal" translate="true">, and you will get the following advantages:</text></para>
    <list id="1" type="ul" listtype="bullet" formatstring="&#183;" format-charset="SYMBOL_CHARSET" levelreset="true" legalstyle="false" startfrom="1" styleclass="Normal (list)" style="font-family:Symbol; font-size:10pt; color:#000000;">
      <li styleclass="Normal (list)"><text styleclass="Normal (list)" translate="true">Models are automatically being watched for changes, thus if a mapped property changes, the View Model is updated accordingly;</text></li>
      <li styleclass="Normal (list)"><text styleclass="Normal (list)" translate="true">When a View Model is changed, this property is automatically mapped to the Model;</text></li>
      <li styleclass="Normal (list)"><text styleclass="Normal (list)" translate="true">When the Model changes, the View Model is initialized automatically with the values of the new Model;</text></li>
      <li styleclass="Normal (list)"><text styleclass="Normal (list)" translate="true">When a Model has an error or warning (business or field), the warnings are mapped to the View Model so you can “re-use” the validation of the Model inside your View Model.</text></li>
    </list>
    <para styleclass="Normal"><text styleclass="Normal" translate="true">So, you get all of this for free? No, you will have to decorate your property with </text><link displaytype="text" defaultstyle="true" type="topiclink" href="T_Catel_MVVM_ViewModelToModelAttribute" styleclass="Normal" translate="true">ViewModelToModelAttribute</link><text styleclass="Normal" translate="true">, like shown below:</text></para>
    <para styleclass="Code Example"><text styleclass="Code Example" style="font-weight:normal; font-style:italic; color:#000000;" translate="true">/// &lt;summary&gt;</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:italic; color:#000000;" translate="true">/// Gets or sets the first name.</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:italic; color:#000000;" translate="true">/// &lt;/summary&gt;</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">[ViewModelToModel(&quot;Person&quot;)]</text><br/><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000000;" translate="true">public</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000000;" translate="true">string</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">FirstName</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">{</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true"> &#160; &#160;</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">get</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">{</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000000;" translate="true">return</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">GetValue&lt;</text><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000000;" translate="true">string</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">&gt;(FirstNameProperty);</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">}</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true"> &#160; &#160;</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">set</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">{</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">SetValue(FirstNameProperty,</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">value);</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">}</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">}</text><br/><br/><text styleclass="Code Example" style="font-weight:normal; font-style:italic; color:#000000;" translate="true">/// &lt;summary&gt;</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:italic; color:#000000;" translate="true">/// Register the FirstName property so it is known in the class.</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:italic; color:#000000;" translate="true">/// &lt;/summary&gt;</text><br/><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000000;" translate="true">public</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000000;" translate="true">static</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000000;" translate="true">readonly</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">PropertyData</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">FirstNameProperty</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">=</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">RegisterProperty(&quot;FirstName&quot;,</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000000;" translate="true">typeof</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">(</text><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000000;" translate="true">string</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">));</text></para>
    <para styleclass="Normal"><text styleclass="Normal" translate="true">The code example is the easiest usage of the attribute that is available. It only provides the name of the Model property. This is required because it is possible (but not likely) to have multiple Models. But what if the property on your Model has a different name than your View Model? No problem, use the overload of the attribute as shown below:</text></para>
    <para styleclass="Code Example"><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">[ViewModelToModel(&quot;Person&quot;,</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">&quot;RealFirstName&quot;)]</text><br/><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000000;" translate="true">public</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000000;" translate="true">string</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">FirstName</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:italic; color:#000000;" translate="true">///... (remaining code left out for the sake of simplicity)</text></para>
    <para styleclass="Normal"><text styleclass="Normal" translate="true">The code above will map the </text><text styleclass="Normal" style="font-style:italic;" translate="true">FirstName</text><text styleclass="Normal" translate="true"> property of the View Model to the </text><text styleclass="Normal" style="font-style:italic;" translate="true">RealFirstName</text><text styleclass="Normal" translate="true"> property of the </text><text styleclass="Normal" style="font-style:italic;" translate="true">Person</text><text styleclass="Normal" translate="true"> model.</text></para>
    <para styleclass="Heading1"><text styleclass="Heading1" translate="true">ExposeAttribute</text></para>
    <para styleclass="Normal"><text styleclass="Normal" translate="true">The </text><link displaytype="text" defaultstyle="true" type="topiclink" href="T_Catel_MVVM_ViewModelToModelAttribute" styleclass="Normal" translate="true">ViewModelToModelAttribute</link><text styleclass="Normal" translate="true"> is a great way to map properties between the model and the view model. However, sometimes the mappings are not required for manual coding and should only be exposed from inside the view model to the view. The </text><link displaytype="text" defaultstyle="true" type="topiclink" href="T_Catel_MVVM_ExposeAttribute" styleclass="Normal" translate="true">ExposeAttribute</link><text styleclass="Normal" translate="true"> is great way to simplify this process. The code below is the same as declaring a model property named </text><text styleclass="Normal" style="font-style:italic;" translate="true">Person</text><text styleclass="Normal" style="font-style:normal;" translate="true"> and 3 additional properties using the </text><link displaytype="text" defaultstyle="true" type="topiclink" href="T_Catel_MVVM_ViewModelToModelAttribute" styleclass="Normal" translate="true">ViewModelToModelAttribute</link><text styleclass="Normal" translate="true">:</text></para>
    <para styleclass="Code Example"><text styleclass="Code Example" style="font-weight:normal; font-style:italic; color:#800000;" translate="true">/// Gets or sets the person.</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:italic; color:#800000;" translate="true">/// &lt;/summary&gt;</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">[Model]</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">[Expose(&quot;FirstName&quot;)]</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">[Expose(&quot;MiddleName&quot;)]</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">[Expose(&quot;LastName&quot;)]</text><br/><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000080;" translate="true">private</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160;Person Person</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">{</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; &#160;get { </text><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000080;" translate="true">return</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> GetValue&lt;Person&gt;(PersonProperty); }</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; &#160;set { SetValue(PersonProperty, value); }</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">}</text><br/><br/><text styleclass="Code Example" style="font-weight:normal; font-style:italic; color:#800000;" translate="true">/// &lt;summary&gt;</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:italic; color:#800000;" translate="true">/// Register the Person property so it is known in the class.</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:italic; color:#800000;" translate="true">/// &lt;/summary&gt;</text><br/><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000080;" translate="true">public</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000080;" translate="true">static</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000080;" translate="true">readonly</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> PropertyData PersonProperty = RegisterProperty(&quot;Person&quot;, </text><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000080;" translate="true">typeof</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">(Person));</text></para>
    <para styleclass="Notes"><text styleclass="Notes" translate="true">This feature is only available in WPF because Silverlight does not provide the ICustomTypeDescriptor or an equivalent feature</text></para>
  </body>
</topic>
